package com.sxt.test;

import java.util.Iterator;

import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Test;

import com.sxt.entity.City;
import com.sxt.entity.User;
import com.sxt.util.HibernateSessionFactory;

public class Demo {

	/**
	 * 即时加载 lazy设置为false
	 */
	@Test
	public void test1() {
		Session session = HibernateSessionFactory.getSession();
		City city = (City) session.get(City.class, 1);
		session.close();
		System.out.print(city.getName() + "--->");

		Iterator<User> it = city.getUsers().iterator();
		while (it.hasNext()) {
			System.out.print(it.next().getUname() + " ");
		}
	}

	/**
	 * 延时加载/懒加载 lazy设置为true
	 */
	@Test
	public void test2() {
		Session session = HibernateSessionFactory.getSession();
		City city = (City) session.get(City.class, 1);
		session.close();
		System.out.print(city.getName() + "--->");

		Iterator<User> it = city.getUsers().iterator();
		while (it.hasNext()) {
			System.out.print(it.next().getUname() + " ");
		}
	}

	/**
	 * Iterate()方法
	 */
	@Test
	public void test3() {
		Session session = HibernateSessionFactory.getSession();
		Query query = session.createQuery("from City");
		@SuppressWarnings("unchecked")
		Iterator<City> it = query.iterate();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		session.close();
	}
	
	/**
	 * 获取User
	 * 采用延时加载
	 * 通过flag变量判断是否需要加载关联对象
	 * @param id 用户id号
	 * @param flag 是否加载关联对象
	 * @return User实体类
	 */
	public User getUser(int id, boolean flag) {
		Session session = HibernateSessionFactory.getSession();
		try {
			User user = (User) session.get(User.class, id);
			if (flag) { 
				//如果需要加载关联数据，则使用此语句初始化关联对象
				Hibernate.initialize(user.getCity());
			}
			return user;
		} catch (Exception e) {
			return null;
		} finally {
			if (session != null) {
				session.close();
				session = null;
			}
		}
	}
	
	/**
	 * 延时加载时，关闭session后再获取关联数据会出错
	 * 需要在关闭前加载关联数据
	 */
	@Test
	public void test4() {
		User user = getUser(3, true);  //如果不加载
		System.out.println(user.getUname());
		System.out.println(user.getCity().getName());  //则出错
	}
	
	/**
	 * 一级缓存测试
	 * @throws InterruptedException 
	 */
	@Test
	public void test5() throws InterruptedException {
		Session session = HibernateSessionFactory.getSession();
		
		double t1 = System.currentTimeMillis();
		User user1 = (User) session.get(User.class, 3);
		double t2 = System.currentTimeMillis();
	
		System.out.println(user1);
		System.out.println("前者查询数据用时"+ (t2 - t1) + "毫秒");
		
		//session.evict(user1);
		
		double t3 = System.currentTimeMillis();
		User user2 = (User) session.get(User.class, 3);
		double t4 = System.currentTimeMillis();
		
		System.out.println(user2);
		System.out.println("后者查询数据用时" + (t4 - t3) + "毫秒");
		
		session.close();
	}
	
	/**
	 * 二级缓存测试
	 */
	@Test
	public void test6() {
		SessionFactory hsf = HibernateSessionFactory.getSessionFactory();
		
		Session session = hsf.openSession();
		User user1 = (User) session.get(User.class, 3);
		System.out.println(user1);
		
		session.close();  //虽然已经关闭了Session，但是仍然可以在二级缓存中读取
		//hsf.evict(User.class);  //如果从二级缓存中清除了User,则需要再从数据库中查
		
		session = hsf.openSession();
		User user2 = (User) session.get(User.class, 3);
		System.out.println(user2);
		
		session.close();
	}
	
	/**
	 * 查询缓存测试
	 */
	@SuppressWarnings("unchecked")
	@Test
	public void test7() {
		Session session = HibernateSessionFactory.getSession();
		String hql = "from User";
		Query query = session.createQuery(hql);
		query.setCacheable(true);  //启用查询缓存
		
		Iterator<User> it1 = query.list().iterator();
		while (it1.hasNext()) {
			System.out.print(it1.next() + "  ");
		}
		
		System.out.println();
		
		Iterator<User> it2 = query.list().iterator();
		while (it2.hasNext()) {
			System.out.print(it2.next() + "  ");
		}
	}
}
